package com.liuqi.voicenotes.reminder

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
import android.os.Build
import android.os.IBinder
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.util.Log
import android.widget.Toast
import androidx.core.app.NotificationCompat
import com.liuqi.voicenotes.R
import java.util.Locale

class ReminderSpeakService : Service() {
    private var tts: TextToSpeech? = null
    private var audioManager: AudioManager? = null
    private var focusRequest: AudioFocusRequest? = null

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onCreate() {
        super.onCreate()
        ensureSpeechChannel()
        audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val title = intent?.getStringExtra("title") ?: "待办提醒"
        val isPre = intent?.getBooleanExtra("is_pre", false) ?: false

        val notification = NotificationCompat.Builder(this, SPEECH_CHANNEL)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle(if (isPre) "语音预提醒" else "语音到期提醒")
            .setContentText(title)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build()
        startForeground((title.hashCode() + if (isPre) 1000 else 2000), notification)
        Log.d(TAG, "startForeground for speak, isPre=$isPre, title=$title")

        val lead = ReminderScheduler.getLeadMinutes(this)
        val speakText = if (isPre) "提醒：${lead}分钟后，$title" else "提醒：$title"
        val audioAttrs = AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY)
            .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
            .build()
        val focusGranted = requestAudioFocus(audioAttrs)
        Log.d(TAG, "audio focus granted=$focusGranted")
        
        // 直接初始化TTS，不检查特定引擎
        tts = TextToSpeech(this) { status ->
            handleTtsInit(status, speakText, audioAttrs)
        }
        
        return START_NOT_STICKY
    }

    private fun handleTtsInit(status: Int, speakText: String, audioAttrs: AudioAttributes) {
        if (status == TextToSpeech.SUCCESS) {
            val targetLocale = if (Locale.getDefault().language.startsWith("zh")) Locale.SIMPLIFIED_CHINESE else Locale.getDefault()
            val avail = tts?.isLanguageAvailable(targetLocale)
            Log.d(TAG, "language available code=$avail for $targetLocale")
            
            // 检查语言是否可用
            if (avail == TextToSpeech.LANG_MISSING_DATA || avail == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.e(TAG, "Language is not supported or missing data for $targetLocale")
            }
            
            val langRes = tts?.setLanguage(targetLocale)
            Log.d(TAG, "setLanguage result=$langRes")
            try { tts?.setAudioAttributes(audioAttrs) } catch (e: Exception) { Log.w(TAG, "setAudioAttributes fail: ${e.message}") }
            val utteranceId = "voicenotes_${System.currentTimeMillis()}"
            tts?.setOnUtteranceProgressListener(object : UtteranceProgressListener() {
                override fun onStart(utteranceId: String?) {}
                override fun onDone(utteranceId: String?) { Log.d(TAG, "tts done"); stopAndRelease() }
                override fun onError(utteranceId: String?) { Log.e(TAG, "tts error"); stopAndRelease() }
                
                // 添加对新版本API的支持
                override fun onError(utteranceId: String?, errorCode: Int) {
                    Log.e(TAG, "tts error, errorCode=$errorCode"); stopAndRelease()
                }
            })
            val r = tts?.speak(speakText, TextToSpeech.QUEUE_FLUSH, null, utteranceId)
            Log.d(TAG, "tts.speak called, result=$r, text=$speakText")
        } else {
            Log.e(TAG, "tts init failed: status=$status")
            // TTS初始化失败，提示用户
            handleNoTTSEngineAvailable()
            stopAndRelease()
        }
    }

    private fun stopAndRelease() {
        try { tts?.shutdown() } catch (_: Exception) {}
        abandonAudioFocus()
        stopForeground(STOP_FOREGROUND_REMOVE)
        stopSelf()
    }

    // 当没有可用的 TTS 引擎时，提示用户安装
    private fun handleNoTTSEngineAvailable() {
        // 在主线程中显示 Toast 提示
        val handler = android.os.Handler(mainLooper)
        handler.post {
            Toast.makeText(this, "未找到可用的语音引擎，请安装 TTS 引擎（如科大讯飞、Google TTS 等）", Toast.LENGTH_LONG).show()
        }
        
        // 尝试启动 TTS 引擎安装页面
        try {
            val intent = Intent("android.speech.tts.engine.INSTALL_TTS_DATA")
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
        } catch (e: Exception) {
            Log.e(TAG, "cannot prompt install TTS: ${e.message}")
            // 如果无法启动安装页面，则引导用户到应用商店搜索 TTS 引擎
            try {
                val intent = Intent(Intent.ACTION_VIEW)
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                // 为国内用户推荐几个常用的 TTS 引擎
                intent.data = android.net.Uri.parse("market://search?q=科大讯飞语音引擎")
                startActivity(intent)
            } catch (e2: Exception) {
                Log.e(TAG, "cannot open market: ${e2.message}")
                // 再尝试搜索小米语音引擎
                try {
                    val intent = Intent(Intent.ACTION_VIEW)
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    intent.data = android.net.Uri.parse("market://search?q=小米语音引擎")
                    startActivity(intent)
                } catch (e3: Exception) {
                    Log.e(TAG, "cannot open market for Xiaomi TTS: ${e3.message}")
                    // 最后的备选方案：打开浏览器访问科大讯飞官网
                    try {
                        val intent = Intent(Intent.ACTION_VIEW)
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        intent.data = android.net.Uri.parse("https://www.iflytek.com")
                        startActivity(intent)
                    } catch (e4: Exception) {
                        Log.e(TAG, "cannot open browser: ${e4.message}")
                    }
                }
            }
        }
    }

    private fun ensureSpeechChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val nm = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            val ch = NotificationChannel(SPEECH_CHANNEL, "语音提醒", NotificationManager.IMPORTANCE_LOW)
            nm.createNotificationChannel(ch)
        }
    }

    companion object {
        private const val TAG = "ReminderSpeakService"
        const val SPEECH_CHANNEL = "voicenotes.speech"
    }

    private fun requestAudioFocus(attrs: AudioAttributes): Boolean {
        return try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val req = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
                    .setAudioAttributes(attrs)
                    .setWillPauseWhenDucked(false)
                    .build()
                focusRequest = req
                audioManager?.requestAudioFocus(req) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
            } else {
                @Suppress("DEPRECATION")
                audioManager?.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
            }
        } catch (e: Exception) {
            Log.w(TAG, "requestAudioFocus fail: ${e.message}")
            false
        }
    }

    private fun abandonAudioFocus() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                focusRequest?.let { audioManager?.abandonAudioFocusRequest(it) }
            } else {
                @Suppress("DEPRECATION")
                audioManager?.abandonAudioFocus(null)
            }
        } catch (e: Exception) {
            Log.w(TAG, "abandonAudioFocus fail: ${e.message}")
        }
    }
}